//
//  XJSqlite3TableTool.swift
//  XJSqlite3Tool
//
//  Created by shanlin on 2017/7/5.
//  Copyright © 2017年 善林(中国)金融信息服务有限公司. All rights reserved.
//
/*
 0: 在navicat里修改表名字以后、语句结构会发生变化：操作步骤
 单击表名字-->点击Edit--> 任意修改一个字段名字、保存-->然后点击 i(More Info) --> DDL就可以看到最新的sql表格结构发生变化了
 
 CREATE TABLE "XJModel" (
     "name" text,
     "age2" integer,
     "id" integer,
     "arr" text,
	PRIMARY KEY("id")
 )
 
 1:表跟新几点：
 01:表字段名称不同
 02:表字段个数不同
 
 2:数据迁移:
 01:比如之前忽略了字段、但是后面又开始加上、这时候就需要更新表、同时迁移数据
 
 3: 排序的原理是:让取出的表字段顺序和当前的表字段顺序进行数组一对一比对、如果顺序都对应上、只是数据不一样、就不需要更新表结构
 */






import UIKit
class XJSqlite3TableTool: NSObject {}


//============================================================
//       Check 1 - 获取旧表中的所有的属性、并且排序
//============================================================
/**
 获取旧表中的所有的属性、并且排序
 
 @param cls 类名
 @return 旧表中所有字段
 */
extension XJSqlite3TableTool {
    class func xj_getTableColumnNamesWithSorted<T: NSObject>(cls: T.Type, uid: String) -> [String] where T: XJSqlite3ModelProtocol  {
        // 1 获取表名称
        let tableName = XJSqlite3ModelManager.xj_getClassName(cls: cls)
        
        // 2 拼接sql语句
        let sqlString = "select sql from sqlite_master where type = 'table' and name = '\(tableName)'"
        
        // 3 通过sql语句查询
        // 一：得到创建表的sql语句结果 ["sql": "// CREATE TABLE XJModel(name text,age integer,id integer,arr text, primary key(id))"]
        
        /* 二：通过最上面的方案操作会出现的格式差异处理: 先强制转(全为小写字母)
         CREATE TABLE "XJModel" (
             "name" text,
             "age2" integer,
             "id" integer,
             "arr" text,
             PRIMARY KEY("id")
         )
         */
        
        let dict = XJSqlite3Tool.share.xj_querySql(sql: sqlString, uid: uid).first ?? [:]
        var sql = (dict["sql"] as? String ?? "").lowercased()
        if sql.characters.count == 0 { return [] }
        
        /* sql.trimmingCharacters(in: CharacterSet.init(charactersIn: "\""))
         1: 这个方法只能过滤两边的空格、中间空格不能过滤
         2: 这个方法不能guo
         */
        //sql = sql.trimmingCharacters(in: CharacterSet.init(charactersIn: "\""))
        sql = sql.replacingOccurrences(of: "\"", with: "")
        sql = sql.replacingOccurrences(of: "\n", with: "")
        sql = sql.replacingOccurrences(of: "\t", with: "")
        
        /* \t:水平制表符
         1:\t过滤前: sqlArrayStr ======	 name text,	 age2 integer,	 id integer,	 arr text,	primary key
         2:\t过滤后: sqlArrayStr ====== name text, age2 integer, id integer, arr text,primary key
         */

        // 4 开始切割数据"("
        let sqlArrayStr = sql.components(separatedBy: "(")[1]
        
        // 5 再次切割数据","
        let columnNameTypeArray = sqlArrayStr.components(separatedBy: ",")
        var newColumnNameArray = [String]()
        for (_,value) in columnNameTypeArray.enumerated() {
            if value.contains("primary") {
                continue
            }
            // 以下是不包含primary
            var name = value.trimmingCharacters(in: CharacterSet.init(charactersIn: " "))
            name = name.components(separatedBy: " ").first ?? ""
            newColumnNameArray.append(name)
        }
        
        // 6 排序前["name", "age", "id", "arr"]  排序后["age", "arr", "id", "name"]
        newColumnNameArray = newColumnNameArray.sorted(by: { (s1, s2) -> Bool in
            return s1 < s2
        })
        return newColumnNameArray
    }
}





//============================================================
//       Check 2 - 表不存在、就创建
//============================================================
/**
 表不存在、就创建
 
 @param cls 类名
 @param uid 用户id
 @return 是否表存在
 */
extension XJSqlite3TableTool {
    class func isTableExists(cls: AnyClass, uid: String) -> Bool {
        let tableName = XJSqlite3ModelManager.xj_getClassName(cls: cls)
        let queryCreateSqlStr = "select sql from sqlite_master where type = 'table' and name = '\(tableName)'"
        let resultArray = XJSqlite3Tool.share.xj_querySql(sql: queryCreateSqlStr, uid: uid)
        return resultArray.count > 0
    }
}
